﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using FileService.Application.Contract.DTO.Output;
using FileService.Application.Contract.IAppService;
using FileService.Domain.Aggregate.File;
using FileService.Domain.Specification;
using FreeRedis;
using LeoGemini.Service.Infrastructure.Extension;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;

namespace FileService.Application.AppService
{
    public class FileAppService : ApplicationService, IFileAppService
    {
        private readonly IRepository<File, Guid> _fileRepository;
        private readonly IWebHostEnvironment _env;
        private readonly RedisClient _cache;
        private readonly IConfiguration _configuration;
        
        public FileAppService(
            IRepository<File, Guid> fileRepository,
            IWebHostEnvironment env,
            RedisClient cache,
            IConfiguration configuration)
        {
            _fileRepository = fileRepository;
            _env = env;
            _cache = cache;
            _configuration = configuration;
        }

        /// <summary>
        /// 上传文件
        /// </summary>
        public async Task<ICollection<UploadFileReturnDto>> UploadAsync(List<IFormFile> files)
        {
            var savedFiles = new List<File>();
            
            foreach (var f in files)
            {
                var hash = f.GetSha1();
                // 缓存/数据库查找
                var file = await _cache.CacheOrGetAsync($"file:hash:{hash}",
                async () => await _fileRepository.FirstOrDefaultAsync(
                    new GetFileBySha1Md5Specification(hash)
                    ));
                
                if (file == null)
                {
                    // 创建文件领域对象
                    file = new File(GuidGenerator.Create(), f, _env.WebRootPath);
                    // 保存文件到本地
                    file.SaveToLocal();
                    await _fileRepository.InsertAsync(file);
                }
                savedFiles.Add(file);
            }
            
            return ObjectMapper.Map<ICollection<File>, ICollection<UploadFileReturnDto>>(savedFiles);
        }
    }
}